package com.aegean.MonitorExamSYS.center.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.aegean.MonitorExamSYS.center.business.CenterBusiness;
import com.aegean.MonitorExamSYS.center.component.ConductionInfoForExaminee;
import com.aegean.MonitorExamSYS.center.component.PositionInfoForExaminee;
import com.aegean.MonitorExamSYS.center.component.SelectConductionInfo;
import com.aegean.MonitorExamSYS.center.component.SelectExaminee;
import com.aegean.MonitorExamSYS.tools.MyTools;
import com.aegean.MonitorExaxSYS.model.ExamPosition;
import com.aegean.MonitorExaxSYS.model.ExamineeQualification;
import com.aegean.MonitorExaxSYS.model.ExamineeValue;
import com.opensymphony.xwork2.ActionSupport;

@Controller("AutoArrangeForExaminee")
@Scope("prototype")
public class AutoArrangeForExaminee extends ActionSupport implements
		ServletRequestAware {
	@Resource
	CenterBusiness business;
	private HttpServletRequest request;
	private HttpSession session;
	private Map<Integer, Map<Integer, List<SelectExaminee>>> examineeMaps;// Map<考点Id,Map<考场Id,List<考生>>>
	private int exam_Id;
	private Map<Integer, List<PositionInfoForExaminee>> positionMaps;// Map<考点Id,List<考场>>
	private List<ConductionInfoForExaminee> conductions;// 存储考点所对应的相关信息
	private Map<Integer, ConductionInfoForExaminee> conductionMaps;// 存储考点对应信息的Map对象，Map<考试资格Id,考点实体>
	private String msg;
	private boolean success;
	private List<SelectExaminee> examinees;
	private Map<Integer, List<SelectExaminee>> unit_ExamineesMap;// 根据考点分配考生
	private List<SelectExaminee> leftExaminee;// 剩余的考生
	private int unit_Id;// 接受到的考点资格id
	private int total;
	private Date time;

	public Date getTime() {
		return time;
	}

	public void setTime(Date time) {
		this.time = time;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public int getUnit_Id() {
		return unit_Id;
	}

	public void setUnit_Id(int unit_Id) {
		this.unit_Id = unit_Id;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public int getExam_Id() {
		return exam_Id;
	}

	public void setExam_Id(int exam_Id) {
		this.exam_Id = exam_Id;
	}

	public List<SelectExaminee> getExaminees() {
		return examinees;
	}

	public void setExaminees(List<SelectExaminee> examinees) {
		this.examinees = examinees;
	}

	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		try {
			conductions = (List<ConductionInfoForExaminee>) session
					.getAttribute("ConductionsForExaminee");
			unit_ExamineesMap = new HashMap<Integer, List<SelectExaminee>>();
			positionMaps = new HashMap<Integer, List<PositionInfoForExaminee>>();
			conductionMaps = new HashMap<Integer, ConductionInfoForExaminee>();
			leftExaminee = new ArrayList<SelectExaminee>();
			for (ConductionInfoForExaminee con : conductions) {
				List<PositionInfoForExaminee> positions = business
						.showPositionListForExaminee(exam_Id, con.getId());
				positionMaps.put(con.getEpq_Id(), positions);
				unit_ExamineesMap.put(con.getEpq_Id(),
						new ArrayList<SelectExaminee>());
				conductionMaps.put(con.getEpq_Id(), con);
			}
			examinees = business.showExamineesList(exam_Id);
			/* 对考生报考与实际申办学校相符的排序 */
			for (SelectExaminee examinee : examinees) {
				if (conductionMaps.containsKey(examinee.getExam_Pq())) {
					if (conductionMaps.get(examinee.getExam_Pq())
							.getPersonCount() > unit_ExamineesMap.get(
							examinee.getExam_Pq()).size()) {
						unit_ExamineesMap.get(examinee.getExam_Pq()).add(
								examinee);
					} else {
						leftExaminee.add(examinee);
					}
				} else {
					leftExaminee.add(examinee);
				}
			}
			/* 对考生报考与审计申办学校不相符的排序 */
			for (SelectExaminee examinee : leftExaminee) {
				List<ConductionInfoForExaminee> cons = this.conductions;
				SortConfirm sort = new SortConfirm();
				sort.setExaminee(examinee);
				Collections.sort(cons, sort);// 通过排序把用户的地理位置，来给所有考点按距离从近到远排序
				for (ConductionInfoForExaminee con : cons) {
					if (con.getPersonCount() > unit_ExamineesMap.get(
							con.getEpq_Id()).size()) {
						unit_ExamineesMap.get(con.getEpq_Id()).add(examinee);
						break;
					}
				}
			}
			session.setAttribute("UnitExamineeForArrangeExaminee",
					unit_ExamineesMap);// 为对应考点安排的考生这是session
			session.setAttribute("PositionMapsForArrangeExaminee", positionMaps);// 对应考点的考场信息session
			success = true;
			msg = "恭喜，系统自动安排考生成功，您可以点击右键查询相应考点分配的考生列表,然后点击总分配完成确认系统的分配！";
		} catch (Exception e) {
			e.printStackTrace();
			success = false;
			msg = "对不起，系统自动安排考生出错，请联系管理员！";
		}
		return SUCCESS;
	}

	public String searchUnit() throws Exception {
		unit_ExamineesMap = (Map<Integer, List<SelectExaminee>>) session
				.getAttribute("UnitExamineeForArrangeExaminee");
		examinees = unit_ExamineesMap.get(unit_Id);
		total = examinees.size();
		return SUCCESS;
	}

	public String confirm() throws Exception {
		examineeMaps = new HashMap<Integer, Map<Integer, List<SelectExaminee>>>();// Map<考点Id,Map<考场Id,List<考生>>>
		unit_ExamineesMap = (Map<Integer, List<SelectExaminee>>) session
				.getAttribute("UnitExamineeForArrangeExaminee");
		positionMaps = (Map<Integer, List<PositionInfoForExaminee>>) session
				.getAttribute("PositionMapsForArrangeExaminee");
		Set<Integer> keys = unit_ExamineesMap.keySet();
		for (Integer key : keys) {// key代表考场资格对应的ID
			Map<Integer, List<SelectExaminee>> peMap = new HashMap<Integer, List<SelectExaminee>>();
			List<PositionInfoForExaminee> positions = positionMaps.get(key);
			List<SelectExaminee> examinees = unit_ExamineesMap.get(key);
			for (PositionInfoForExaminee p : positions) {
				if (p.getExamPosition_PersonCount() >= examinees.size()) {
					peMap.put(p.getExamPQ_Id(), examinees);
					break;
				} else {
					examinees = examinees.subList(0,
							p.getExamPosition_PersonCount());
					peMap.put(p.getExamPQ_Id(), examinees);
				}
			}
			examineeMaps.put(key, peMap);
		}
		success = business.confirmExaminees(examineeMaps, time,exam_Id);
		if (success == true) {
			msg = "恭喜,考生安排与确认已经成功！";
			String[] deleteSession = { "UnitExamineeForArrangeExaminee",// 删除每一个考点对应的考场对应的考生
					"PositionMapsForArrangeExaminee",// 删除每个考场对应的考生实体
					"ConductionsForExaminee"};// 删除该所有考点资格实体
			for (String string : deleteSession) {
				if (session.getAttribute(string) == null) {
					continue;
				} else {
					session.removeAttribute(string);
				}
			}
		} else {
			msg = "对不起，考生安排确认失败，请联系管理员！";
		}
		return SUCCESS;
	}

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		// TODO Auto-generated method stub
		this.request = arg0;
		this.session = request.getSession();

	}

	class SortConfirm implements Comparator<ConductionInfoForExaminee> {
		private SelectExaminee examinee;

		public SelectExaminee getExaminee() {
			return examinee;
		}

		public void setExaminee(SelectExaminee examinee) {
			this.examinee = examinee;
		}

		@Override
		public int compare(ConductionInfoForExaminee o1,
				ConductionInfoForExaminee o2) {
			// TODO Auto-generated method stub
			int result;
			ConductionInfoForExaminee one = (ConductionInfoForExaminee) o1;
			ConductionInfoForExaminee two = (ConductionInfoForExaminee) o2;
			result = MyTools.GetDistance(examinee.getPlace_H(),
					examinee.getPlace_V(), one.getPlace_H(), one.getPlace_V()) < MyTools
					.GetDistance(examinee.getPlace_H(), examinee.getPlace_V(),
							two.getPlace_H(), two.getPlace_V()) ? 1 : (MyTools
					.GetDistance(examinee.getPlace_H(), examinee.getPlace_V(),
							one.getPlace_H(), one.getPlace_V()) < MyTools
					.GetDistance(examinee.getPlace_H(), examinee.getPlace_V(),
							two.getPlace_H(), two.getPlace_V()) ? 0 : -1);
			return result;
		}

	}

}
